package com.source.labelAndBarcode.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.source.baseData.entity.PoultryCategory;
import com.source.baseData.entity.PoultryCategoryParent;
import com.source.baseData.entity.Stalls;
import com.source.baseData.entity.ToMarket;
import com.source.baseData.mapper.PoultryCategoryMapper;
import com.source.baseData.mapper.ToMarketMapper;
import com.source.baseData.service.PoultryCategoryParentService;
import com.source.baseData.service.PoultryCategoryService;
import com.source.baseData.service.StallsService;
import com.source.baseData.service.ToMarketService;
import com.source.baseData.vo.PoultryCategoryVo;
import com.source.baseData.vo.PoultryParentVo;
import com.source.baseData.vo.ToMarketVO;
import com.source.labelAndBarcode.entity.LabelingRecord;
import com.source.labelAndBarcode.mapper.LabelingRecordMapper;
import com.source.labelAndBarcode.service.LabelingRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.source.labelAndBarcode.vo.*;
import com.source.utils.MyPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Joey
 * @since 2021-02-23
 */
@Service
public class LabelingRecordServiceImpl extends ServiceImpl<LabelingRecordMapper, LabelingRecord> implements LabelingRecordService {

    @Autowired
    LabelingRecordMapper recordMapper;

    @Autowired
    StallsService stallsService;

    @Autowired
    PoultryCategoryService categoryService;

    @Autowired
    ToMarketService marketService;

    @Autowired
    PoultryCategoryParentService parentService;



    @Override
    public int weeklyRecord(Integer id) {
        return recordMapper.weeklyRecord(id);
    }

    @Override
    public int monthlyRecord(Integer id) {
        return recordMapper.monthlyRecord(id);
    }

    @Override
    public List<Map<String, BigInteger>> dailyRecordByPoultry(Integer id) {
        return recordMapper.dailyRecordByPoultry(id);
    }

    @Override
    public List<Map<String, BigInteger>> weeklyRecordByPoultry(Integer id) {
        return recordMapper.weeklyRecordByPoultry(id);
    }

    @Override
    public List<Map<String, BigInteger>> monthlyRecordByPoultry(Integer id) {
        return recordMapper.monthlyRecordByPoultry(id);
    }

    @Override
    public List<Map<Object, Object>> dailyRecordByPoultryAndToMark(Integer id) {
        return recordMapper.dailyRecordByPoultryAndToMark(id);
    }

    @Override
    public List<Map<Object, Object>> weeklyRecordByPoultryAndToMark(Integer id) {
        return recordMapper.weeklyRecordByPoultryAndToMark(id);
    }

    @Override
    public List<Map<Object, Object>> monthlyRecordByPoultryAndToMark(Integer id) {
        return recordMapper.monthlyRecordByPoultryAndToMark(id);
    }

    @Override
    public IPage<BarcodeCountVo> findByLikeNameAndTimeOnPagination(Page<BarcodeCountVo> page, String keyWord, Date startDate, Date endDate) {
        return recordMapper.findByLikeNameAndTimeOnPagination(page, "%" + keyWord + "%", startDate, endDate);
    }

    @Override
    public IPage<BarcodeCountVo> findMonthly(Page<BarcodeCountVo> page) {
        return recordMapper.findMonthly(page);
    }

    @Override
    public IPage<BarcodeCountVo> findAllOnPagination(Page<BarcodeCountVo> page) {
        return recordMapper.findAllOnPagination(page);
    }

    @Override
    public BarcodeCountVo findById(String id) {
        return recordMapper.findById(id);
    }

    @Override
    public TraceSrcVo getSrc(String barcodeNumber) {
        TraceSrcVo srcVo = new TraceSrcVo();

        QueryWrapper<LabelingRecord> wrapper = new QueryWrapper<LabelingRecord>();
        wrapper.eq("barcodeNumber",barcodeNumber);
        LabelingRecord record = recordMapper.selectOne(wrapper);

        Integer stallsId = record.getStallsId();
        String toMarketId = record.getToMarketId();
        String poultryCategoryId = record.getPoultryCategoryId();

        StallsVo stallsVo = stallsService.findById(stallsId.toString());
        ToMarket toMarket = marketService.getById(toMarketId);
        PoultryCategoryVo poultryCategoryVo = categoryService.getOneVoById(poultryCategoryId);

        srcVo.setRecord(record);
        srcVo.setPoultryCategoryVo(poultryCategoryVo);
        srcVo.setStallsVo(stallsVo);
        srcVo.setToMarket(toMarket);

        return srcVo;
    }

    @Override
    public IPage<DetailedRecordVo> findAllDROnPagination(Page<DetailedRecordVo> page) {
        return recordMapper.findAllDROnPagination(page);
    }

    @Override
    public IPage<DetailedRecordVo> findAllDRByLikeNameOnPagination(Page<DetailedRecordVo> page, String keyWord) {
        return recordMapper.findAllDRByLikeNameOnPagination(page, "%" + keyWord + "%");
    }


    @Override
    public IPage<PoultryDateSaleVo> findByMultiKeyWord(String stallsName, String contacts, Date startDate, Date endDate, Page<PoultryDateSaleVo> page) throws ParseException {
        stallsName = (stallsName == null ? "%%" : "%" + stallsName + "%");
        contacts = (contacts == null ? "%%" : "%" + contacts + "%");
        endDate = (endDate == null ? new Date() : endDate);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        startDate = (startDate == null ? df.parse("1970-01-01") : startDate);


        IPage<PoultryDateSaleVo> voIPage = recordMapper.findByMultiKeyWord(stallsName, contacts, startDate, endDate, page);
        List<PoultryDateSaleVo> records = voIPage.getRecords();
        List<PoultryDateVo> countsByDay = recordMapper.findCountsByDay(stallsName, contacts, startDate, endDate);
        // 两个对象，voIPage是去重后的日期，list集合现在为空，另一个是不去重日期的集合，用于处理voIPage中的空list集
        // 日期已经排好序
        for (int i = 0, j = 0; j < records.size(); ) {
            //i是 countsByDay的计数，j是records的计数，且j必然比i小
            PoultryDateSaleVo dateSaleVo = records.get(j);
            PoultryDateVo dateVo = countsByDay.get(i);
            //new新集合，进行去重处理
            List<PoultrySaleVo> poultryparentlist = new ArrayList<PoultrySaleVo>();
            while (null != dateVo && dateSaleVo.getSaleDate().equals(dateVo.getSaleDate())) {
                //当两个日期相同的时候，将不去重集合的salecount和禽类名字加入到去重集合的list集合中，需要处理禽类数量增加
                PoultrySaleVo saleVo = new PoultrySaleVo();
                saleVo.setSaleCount(dateVo.getSaleCount());
                saleVo.setPoultryParentName(dateVo.getPoultryParentName());
                poultryparentlist.add(saleVo);
                if(i + 1 < countsByDay.size()){
                    i = i + 1;
                }else {
                    break;
                }
                dateVo = countsByDay.get(i);
            }
            dateSaleVo.setPoultryParentList(poultryparentlist);
            records.set(j++,dateSaleVo);
        }
        voIPage.setRecords(records);

        return voIPage;
    }

    @Override
    public IPage<PoultrySaleVo> findCountsByTime(String stallsName, String contacts, Date startDate, Date endDate, Page<PoultrySaleVo> page) throws ParseException {
        stallsName = (stallsName == null ? "%%" : "%" + stallsName + "%");
        contacts = (contacts == null ? "%%" : "%" + contacts + "%");
        endDate = (endDate == null ? new Date() : endDate);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        startDate = (startDate == null ? df.parse("1970-01-01") : startDate);
        return recordMapper.findCountsByTime(stallsName, contacts, startDate, endDate,page);
    }

    @Override
    public DetailedRecordVo findDetailedRecordById(String id) {
        return recordMapper.findDetailedRecordById(id);
    }

    @Override
    public IPage<PoultrySaleVo2> findCounts(String stallsName, String contacts, Date startDate, Date endDate, Page<PoultrySaleVo2> page) throws ParseException {
        stallsName = (stallsName == null ? "%%" : "%" + stallsName + "%");
        contacts = (contacts == null ? "%%" : "%" + contacts + "%");
        endDate = (endDate == null ? new Date() : endDate);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        startDate = (startDate == null ? df.parse("1970-01-01") : startDate);



        return recordMapper.findCounts(stallsName, contacts, startDate, endDate,page);
    }

    @Override
    public Object findCountsGroupByDay(String stallsName, String contacts, Date startDate, Date endDate, Page<PoultryDateSaleVo> page) throws ParseException {
        stallsName = (stallsName == null ? "%%" : "%" + stallsName + "%");
        contacts = (contacts == null ? "%%" : "%" + contacts + "%");
        endDate = (endDate == null ? new Date() : endDate);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        startDate = (startDate == null ? df.parse("1970-01-01") : startDate);
        Integer current = (int)page.getCurrent();
        Integer size = (int)page.getSize();

        //获取表头
        List<PoultryCategoryParent> parentList = parentService.list();
        //处理表头
        List<PoultryParentVo> pL = new ArrayList<>();
        for (PoultryCategoryParent poultryCategoryParent : parentList) {
            PoultryParentVo p = new PoultryParentVo();
            p.setParentName(poultryCategoryParent.getPoultryParentName());
            p.setParentId(poultryCategoryParent.getPoultryCategoryParentId());
            pL.add(p);
        }

        Page tableData = MyPage.list2Page(current, size, pL);
        //表头end



        //先获取去重后的日期（只是一个日期），降序排列
        List<PoultryDateSaleVo> poultryDateSaleVoList = recordMapper.findByMultiKeyWordVer2(stallsName, contacts, startDate, endDate);
        //将时间存到另一个list集合中
        List<PoultryDateSaleVo2> poultryDateSaleVo2List = new ArrayList<>();
        for (PoultryDateSaleVo dateSaleVo : poultryDateSaleVoList) {
            PoultryDateSaleVo2 p = new PoultryDateSaleVo2();
            p.setSaleDate(dateSaleVo.getSaleDate());
            poultryDateSaleVo2List.add(p);
        }




        //获取根据日期获得的对应禽类日期（未去重）、数量、id
        List<PoultryDateVo2> countsByDay = recordMapper.findCountsByDayVer2(stallsName, contacts, startDate, endDate);
        //saleDate：时间
        //id值：数量
        //sum：总数
        //这些是同级别的，所以要用List集合内存放多个Hashtable
        List<Hashtable<String,Object>> result = new ArrayList<>();
        //开始根据日期去重
        for (PoultryDateSaleVo2 p2 : poultryDateSaleVo2List) {
            Date saleDate = p2.getSaleDate();
            //每次都要遍历一遍未去重的list集合，以匹配到对应的时间
            Hashtable<String,Object> h = new Hashtable<>();
            //将所有的ID都reset好，hashtable里面自己会判断id是否相同，然后换新的count
            for (PoultryParentVo parentVo : pL) {
                h.put(parentVo.getParentId(), 0);
            }
            int sum = 0;
            for (PoultryDateVo2 poultryDateVo2 : countsByDay) {
                if(saleDate.equals(poultryDateVo2.getSaleDate())){
                    //找到之后，设置ID和count
                    //增加到hashtable里面
                    h.put(poultryDateVo2.getPoultryParentId(),poultryDateVo2.getSaleCount());
                    sum = sum + poultryDateVo2.getSaleCount();
                }
            }
            //加上日期和总数，存入list集合中
            h.put("saleDate",saleDate);
            h.put("sum",sum);
            result.add(h);
        }

        Page table = MyPage.list2Page(current, size, result);



        Hashtable<String,Object> data = new Hashtable<>();
        data.put("table", table);

        //处理完毕
        data.put("tableData",tableData);


        return data;
    }
}
